package com.xqboss.apps.service.order.type.impl;

import com.xqboss.apps.constant.Config;
import com.xqboss.apps.domain.order.OrderItem;
import com.xqboss.apps.domain.order.OrderMain;
import com.xqboss.apps.domain.sys.SysRechargeAmountConfig;
import com.xqboss.apps.dto.order.CreateOrderDto;
import com.xqboss.apps.enums.order.OrderTypeEnum;
import com.xqboss.apps.enums.user.UserWalletEnum;
import com.xqboss.apps.enums.user.WalletChangeTypeEnum;
import com.xqboss.apps.service.order.OrderService;
import com.xqboss.apps.service.order.type.OrderTypeExecutor;
import com.xqboss.apps.service.sys.SysRechargeAmountConfigService;
import com.xqboss.apps.service.user.SysUserWalletService;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.common.utils.StringUtils;
import com.xqboss.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Objects;

/**
 * <p>
 *     充值订单执行器
 * </p>
 * @author Trent
 * @date 2023/8/23
 */
@Slf4j
@Component(value = OrderTypeEnum.Code.Recharge)
public class RechargeOrderTypeExecutor extends OrderTypeExecutor {

    @Autowired
    private SysRechargeAmountConfigService rechargeAmountConfigService;

    @Autowired
    private SysUserWalletService userWalletService;

    @Autowired
    @Lazy
    private OrderService orderService;

    @Autowired
    private ISysConfigService sysConfigService;

    @Override
    protected OrderMain preValidate(CreateOrderDto params) {
        if(params.getQuantity() != 1){
            throw new ServiceException("订单数量错误");
        }
        OrderMain order = buildOrder(params);
        OrderItem orderItem = buildOrderItem(order, params);
        order.setOrderItems(Collections.singletonList(orderItem));
        // 15分钟后取消订单
        order.setAutoCancelTime(LocalDateTime.now().plusMinutes(sysConfigService.getValue(Config.Sys.Order.订单超时时间)));

        // 优先取充值商品
        if(Objects.nonNull(params.getSourceId())){
            SysRechargeAmountConfig amountConfig = rechargeAmountConfigService.getById(params.getSourceId());
            if(amountConfig == null){
                throw new ServiceException("充值金额不存在！");
            }
            params.setPrice(amountConfig.getPaymentAmount());

            order.setTotalAmount(amountConfig.getRechargeAmount());
            order.setPaymentAmount(amountConfig.getPaymentAmount());

            orderItem.setTotalAmount(amountConfig.getRechargeAmount());
            orderItem.setPaymentAmount(amountConfig.getRechargeAmount());
            orderItem.setSkuPrice(amountConfig.getRechargeAmount());
            orderItem.setSkuCnt(params.getQuantity());
            orderItem.setSpuName(amountConfig.getSpuName());
            orderItem.setSpuId(amountConfig.getId());
        }else{
            if(params.getPrice().doubleValue() <= 0){
                throw new ServiceException("充值金额错误！");
            }
            // 充值金额判断
            BigDecimal minPrice = sysConfigService.getValue(Config.Sys.Recharge.最低充值金额);
            if(Objects.nonNull(minPrice)){
                if(params.getPrice().compareTo(minPrice) < 0){
                    throw new ServiceException(StringUtils.format("最低充值金额：{}!", minPrice));
                }
            }
            BigDecimal maxPrice = sysConfigService.getValue(Config.Sys.Recharge.最高充值金额);
            if(Objects.nonNull(maxPrice)){
                if(params.getPrice().compareTo(maxPrice) > 0){
                    throw new ServiceException(StringUtils.format("最大充值金额：{}!", maxPrice));
                }
            }

            order.setTotalAmount(params.getPrice());
            order.setPaymentAmount(params.getPrice());

            orderItem.setTotalAmount(params.getPrice());
            orderItem.setPaymentAmount(params.getPrice());
            orderItem.setSkuPrice(params.getPrice());
            orderItem.setSkuCnt(params.getQuantity());
            orderItem.setSkuPrice(params.getPrice());
            orderItem.setSpuName("自定义充值");
        }
        return order;
    }

    @Override
    protected void lockStock(Long sourceId, Integer quantity) {

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderPayedPost(OrderMain order) {
        // 充值
        Long userId = order.getBuyerUserId();
        BigDecimal amount = order.getTotalAmount();
        userWalletService.increase(userId, UserWalletEnum.CASH, amount, WalletChangeTypeEnum.RECHARGE, order.getId(), "用户充值");
        // 更新订单状态为完成
        orderService.complete(order.getId(), null);
    }

}
